//
// Created by liaoyang on 2023-12-11.
//

#include "bsp_usart.h"
#include "task_communicate.h"

#define JUDGE_FIFO_BUFLEN 1250
//该参数应大于等于UART_RX_DMA_SIZE，避免遗漏数据

extern uint8_t remote_Rx_Buffer[RC_FRAME_LENGTH];//原始数据位置

extern uint8_t   judge_rxdata_buf[JUDGE_FIFO_BUFLEN];
extern usart_param_struct judgement_usart;
extern osSemaphoreId_t RemoteSemHandle;
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
    //Size为DMA已接收的数据长度
    if (huart->Instance == USART3)
    {
        HAL_UARTEx_ReceiveToIdle_DMA(&huart3, (uint8_t*)remote_Rx_Buffer, RC_FRAME_LENGTH);
		__HAL_DMA_DISABLE_IT(huart3.hdmarx, DMA_IT_HT);
        osSemaphoreRelease(RemoteSemHandle);
    }
    if(huart->Instance == USART6)
    {
        //暂停DMA数据传输
        //HAL_UART_DMAStop(huart);

        //将DMA　buffer中数据传给FIFO
        /*
         * 理想情况下，每帧数据均从DMA数组首位开始存放（即第一位为A5），实际上由于各个包传输频率不同，
         * 串口空闲中断不明显，可能存在数据接收出错，导致包头A5前仍有其他杂数据
         * 
         * */
        usart_rx_processed( &judgement_usart, Size);

        /*
         * 开启DMA数据传输
         * judgement_usart.buff为传输地址，当空闲中断发生或DMA传输数据达到buff_size时进入中断
         * */
        HAL_UARTEx_ReceiveToIdle_DMA(judgement_usart.huart,judgement_usart.buff,judgement_usart.buff_size);

        //为避免接收数据错误，不在此处喂狗，而且数据校验解算后喂狗
        return;
    }
}

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
    judgement_usart.tx_finish_flag = 1;
}

void usart_dma_send(usart_param_struct *usart_param, const uint8_t *pData, uint32_t _size)
{

    if(usart_param->tx_finish_flag){
        HAL_StatusTypeDef status = HAL_UART_Transmit_DMA(usart_param->huart, pData, _size);
        if(status==HAL_OK)
        {
            usart_param->tx_finish_flag = 0;
        }
        else
        {
            usart_param->tx_finish_flag = 1;
        }
        __HAL_DMA_DISABLE_IT(usart_param->huart->hdmatx, DMA_IT_HT);
    }
}

void usart_communicate_config(usart_param_struct *usart_param)
{
    //再次开启DMA数据传输
    HAL_UARTEx_ReceiveToIdle_DMA(usart_param->huart,
                                 usart_param->buff,
                                 usart_param->buff_size);
    __HAL_DMA_DISABLE_IT(usart_param->huart->hdmarx, DMA_IT_TC);
    __HAL_DMA_DISABLE_IT(usart_param->huart->hdmarx, DMA_IT_HT);
}

void USART1ConfigEnable(uint8_t *DMA_Memory0BaseAddr, uint8_t DMA_BufferSize)
{
    //SrcAddress:USART1->DR;DstAddress:Usart1DMAMemoryBaseAddress
    HAL_UARTEx_ReceiveToIdle_DMA(&huart3, (uint8_t*)DMA_Memory0BaseAddr, DMA_BufferSize);
    __HAL_DMA_DISABLE_IT(huart3.hdmarx, DMA_IT_HT);
}
